|
M3G 1.1 -- Jun 22, 2005 | |||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object javax.microedition.m3g.Object3D javax.microedition.m3g.Transformable javax.microedition.m3g.Node
An abstract base class for all scene graph nodes.
There are five different kinds of nodes:
Camera
defines the projection from 3D to 2D, as well as
the position of the viewer in the scene.Mesh
defines a 3D object, consisting of triangles with
associated material properties.Sprite3D
defines a screen-aligned 2D image with a position
in 3D space.Light
defines the position, direction, color and other
attributes of a light source.Group
serves as a root for scene graph branches.Each node defines a local coordinate system that can be transformed relative to the coordinate system of the parent node. The transformation from the local coordinate system of a node to the coordinate system of its parent is called the node transformation.
The node transformation consists of four parts: a generic matrix M, a non-uniform scale S, an orientation R and a translation T. The bottom row of M must be equal to (0 0 0 1). The methods to manipulate the individual components are defined in the base class, Transformable.
To transform a point from a node's local coordinates to its parent's coordinates, the point is multiplied by the transformation components in the order that they are listed above. Formally, a homogeneous vector p = (x, y, z, 1), representing a 3D point in the local coordinate system, is transformed into p' = (x', y', z', 1) in the parent coordinate system as follows:
The translation, orientation and scale components of the node
transformation can be animated independently from each other. The
matrix component is not animatable at all; it can only be changed
using the setTransform
method.
A node may be aligned with respect to a selected reference node (or nodes). This means that the aligned node is, upon request, automatically oriented so that its coordinate system matches the reference node's coordinate system in the specified way. A common use case for node alignment is to create "billboards" that are always facing the camera; another is to make the camera always point at a certain object.
When a node is aligned, its original orientation component R is overwritten with an aligned orientation A. (The aligned orientation is computed as specified below, in the Implementation Guidelines section.) The other components of the node transformation are not affected by alignment. The transformation from the local coordinate system of an aligned node to its parent node's coordinate system is, therefore,
The application must explicitly call the align
method on
a node (or any of its ancestors) when it requires the alignments of that
node and its descendants to be computed. This is typically done once per
frame, before rendering. Rendering operations do not resolve any alignments;
they simply use whatever orientation each node has at that time. The same
holds true for getTransformTo
and any other methods whose
results depend on the orientation.
The alignment reference node(s) and the method of alignment are selected
with setAlignment
. This does not yet compute the new aligned
orientation, but merely specifies how that is to be done. Optionally, the
reference node may be left unspecified (null) until when align
is called; the reference node is then supplied as a parameter to
align
. This is very useful for billboards, because otherwise
the application would have to call setAlignment
separately for
every billboard in the scene whenever the camera is changed.
Besides the node transformation, there are three node properties whose effective values are in some manner influenced by the ancestors of each node. These properties are the alpha factor, the rendering enable flag, and the picking enable flag.
The alpha factor allows (groups of) Mesh and Sprite3D objects to be faded in and out in a convenient way, provided that certain preconditions related to their Appearance are met. The alpha factor is defined for each Node, and its value is between [0, 1]. The effective alpha factor for an object is obtained by multiplying its local alpha factor with the alpha factors of its ancestors. The alpha factor is ignored for Light and Camera nodes.
When rendering a Mesh, its effective alpha factor is multiplied
with the alpha component of the diffuse color in each of the Material
objects associated with that Mesh. In absence of a Material object,
the alpha factor is applied to the alpha channel of
the VertexBuffer color array, or if the color array is null, the default
color alpha component. When rendering a Sprite3D, its effective
alpha factor is multiplied with the alpha channel of the sprite image.
Note that for both meshes and sprites, only the alpha values are ever
modified. The alpha factor alone is therefore not
sufficient for a fade-in/fade-out effect. Instead, the texture
blending mode, the framebuffer blending mode, and the alpha threshold
must all be set appropriately. For meshes, setting texture blending to
MODULATE
, framebuffer blending to ALPHA
, and
alpha threshold to zero will often produce the desired result. Sprites
should use a non-zero alpha threshold and ALPHA
blending
in CompositingMode.
The enable flags for rendering and picking allow (groups of) mesh and sprite objects to be made "invisible" from the point of view of rendering and picking, respectively. The effective enable status of a node is the logical AND of the enable flags on that node and all its ancestors. Therefore, setting the enable flag of a node to true does not guarantee that the node will be rendered or picked. Rather, if any of its ancestors are disabled, the node will be ignored regardless of its own enable flag.
Note that the scope of a Node is not an inherited property; see below for more information.
The scope of a Node is an integer bitmask that allows scene graph nodes to form conceptual groups independent of the scene graph hierarchy. In other words, nodes that are in a particular Group are not necessarily in the same scope. Formally, two nodes A and B are defined to be in the same scope if the bitwise AND of their scopes is non-zero:
Scopes are not hierarchic in any way. In particular, the scope of a Group or SkinnedMesh node is not propagated to or inherited by its children. After all, scopes are intended to be separate from the scene hierarchy.
Scoping serves three purposes:
pick
methods in Group. Again, only those objects can be
picked that are in the same scope as the pick ray; the others are
ignored.The default scope is -1, implying that all nodes are in the same scope. By default, all objects are therefore visible to all cameras, and are lit by all light sources.
Node is an abstract class, and therefore has no public constructor. When a class derived from Node is instantiated, the attributes defined in Node will have the following default values:
NONE
, null ) for all axesThe alignment rotation A is computed relative to the initial coordinate system A defined by the T component of the node transformation alone. All other transformation components of the node being aligned are ignored.
Conceptually, alignment is composed of two cumulative rotations: the shortest rotation Rz that takes the initial Z axis to the Z alignment target vector, followed by the rotation Ry about the resulting Z vector that minimizes the angle between the resulting Y axis and the Y alignment target vector. If alignment is set for one axis only, that rotation is performed like the initial Z rotation.
Formally, let us denote by tZ and tY the Z and Y alignment target vectors, transformed from their respective reference nodes to A; note that axis targets transform as vectors, and origin targets as points. The axis for the first rotation Rz is then the cross product of the local Z axis of A and the target vector:
and the rotation angle can be computed via the dot product of the two. Rotating by Rz takes us to a new coordinate frame B where tY is expressed as:
The axis for the second rotation RY is the local Z axis of B, and the angle is the angle between the local Y axis and the projection of tY' on the XY plane. The final alignment rotation A is then:
There are two cases where a rotation axis is undefined. Firstly, if either target vector coincides with the axis that it is a target for, the respective rotation must be substituted with an identity rotation. Secondly, if the target vector and the axis are opposite, the exact rotation path (that is, the resultant direction of the other two axes) is implementation dependent, but must be deterministic. Note that the latter only matters for unconstrained (single-axis) alignment.
Field Summary | |
static int |
NONE
Specifies for the setAlignment method that no
alignment should be done for the specified axis. |
static int |
ORIGIN
Specifies the origin of the reference node as an orientation reference for the setAlignment method. |
static int |
X_AXIS
Specifies the X axis of the reference node as an orientation reference for the setAlignment method. |
static int |
Y_AXIS
Specifies the Y axis of the reference node as an orientation reference for the setAlignment method. |
static int |
Z_AXIS
Specifies the Z axis of the reference node as an orientation reference for the setAlignment method. |
Method Summary | |
void |
align(Node reference)
Applies alignments to this Node and its descendants. |
Node |
getAlignmentReference(int axis)
Returns the alignment reference node for the given axis. |
int |
getAlignmentTarget(int axis)
Returns the alignment target for the given axis. |
float |
getAlphaFactor()
Retrieves the alpha factor of this Node. |
Node |
getParent()
Returns the scene graph parent of this node. |
int |
getScope()
Retrieves the scope of this Node. |
boolean |
getTransformTo(Node target,
Transform transform)
Gets the composite transformation from this node to the given node. |
boolean |
isPickingEnabled()
Retrieves the picking enable flag of this Node. |
boolean |
isRenderingEnabled()
Retrieves the rendering enable flag of this Node. |
void |
setAlignment(Node zRef,
int zTarget,
Node yRef,
int yTarget)
Sets this node to align with the given other node(s), or disables alignment. |
void |
setAlphaFactor(float alphaFactor)
Sets the alpha factor for this Node. |
void |
setPickingEnable(boolean enable)
Sets the picking enable flag of this Node. |
void |
setRenderingEnable(boolean enable)
Sets the rendering enable flag of this Node. |
void |
setScope(int scope)
Sets the scope of this node. |
Methods inherited from class javax.microedition.m3g.Transformable |
getCompositeTransform, getOrientation, getScale, getTransform, getTranslation, postRotate, preRotate, scale, setOrientation, setScale, setTransform, setTranslation, translate |
Methods inherited from class javax.microedition.m3g.Object3D |
addAnimationTrack, animate, duplicate, find, getAnimationTrack, getAnimationTrackCount, getReferences, getUserID, getUserObject, removeAnimationTrack, setUserID, setUserObject |
Field Detail |
public static final int NONE
Specifies for the setAlignment
method that no
alignment should be done for the specified axis.
public static final int ORIGIN
Specifies the origin of the reference node as an orientation
reference for the setAlignment
method.
public static final int X_AXIS
Specifies the X axis of the reference node as an orientation
reference for the setAlignment
method.
public static final int Y_AXIS
Specifies the Y axis of the reference node as an orientation
reference for the setAlignment
method.
public static final int Z_AXIS
Specifies the Z axis of the reference node as an orientation
reference for the setAlignment
method.
Method Detail |
public void setRenderingEnable(boolean enable)
Sets the rendering enable flag of this Node. The effective rendering enable status for this node is the logical AND of the enable flags on this node and all its ancestors. Therefore, the node is disabled if any of its ancestors are. The node's own status has an effect only if all the ancestors are enabled.
If the effective status is true, this node is enabled for rendering; otherwise, it is disabled. Sprite3D, Mesh and Light nodes are turned on and off with this setting, but on Camera nodes it is ignored.
enable
- true to enable rendering; false to disablepublic void setPickingEnable(boolean enable)
Sets the picking enable flag of this Node. The effective picking enable status for this node is the logical AND of the enable flags on this node and all its ancestors. Therefore, the node is disabled if any of its ancestors are. The node's own status has an effect only if all the ancestors are enabled.
If the effective status is true, this node is enabled for picking; otherwise, it is disabled. This setting is ignored for Lights and Cameras, because they are unpickable in any case.
enable
- true to enable picking; false to disablepublic void setScope(int scope)
Sets the scope of this node. The scope is used to limit the set of nodes that are taken into account in rendering, lighting and picking. See the class description for more information.
scope
- the new scope for this nodegetScope
public void setAlphaFactor(float alphaFactor)
Sets the alpha factor for this Node. This can be used to fade groups of meshes and sprites in and out. The alpha factor has no effect on Light and Camera nodes. See the class description for more information.
alphaFactor
- the new alpha factor for this node; must be [0, 1]
java.lang.IllegalArgumentException
- if alphaFactor
is
negative or greater than 1.0getAlphaFactor
public boolean isRenderingEnabled()
Retrieves the rendering enable flag of this Node. Note that this is not the effective rendering enable status, but only the local status of this Node.
setRenderingEnable
public boolean isPickingEnabled()
Retrieves the picking enable flag of this Node. Note that this is not the effective picking enable status, but only the local status of this Node.
setPickingEnable
public int getScope()
Retrieves the scope of this Node.
setScope
public float getAlphaFactor()
Retrieves the alpha factor of this Node. Note that this is not the effective alpha factor, but only the local alpha factor of this Node. To put it another way, the alpha factors of any ancestors to this Node are not multiplied in.
setAlphaFactor
public Node getParent()
Returns the scene graph parent of this node.
public boolean getTransformTo(Node target, Transform transform)
Gets the composite transformation from this node to the given node. The composite transformation is defined to be such that it transforms a point in the local coordinate system of this node to the coordinate system of the given node. For example, the composite transformation from this node to its parent is equal to the node transformation of this node. Similarly, the composite transformation from this node to its child is equal to the inverse of the node transformation of the child.
If there is no path from this node to the given node, this method returns false. On the other hand, if there is a path but the transformation cannot be computed due to a singular transformation, an ArithmeticException is thrown. Beware that a transformation that is invertible in one implementation may not be invertible in another, because of different arithmetic accuracy. To be safe, avoid matrix elements with very small or very large absolute values. See also the package description.
target
- transformation target nodetransform
- transform object to receive the transformation; if
there is no path to the target node, the contents of the object
are left undefined
java.lang.NullPointerException
- if target
is null
java.lang.NullPointerException
- if transform
is null
java.lang.ArithmeticException
- if the inverse of a transformation along
the path is required, but can not be computedpublic final void align(Node reference)
Applies alignments to this Node and its descendants.
The aligned orientation for this node and all its descendants are calculated in an undefined order. The rare case where there are chains of dependencies between aligned objects is therefore not necessarily taken into account.
The orientation component of the node transformation of each aligned node is overwritten with the aligned orientation. The pre-existing orientation is not preserved.
A reference node can be passed in to this method, in order to allow alignment of objects to a common reference that is determined at run time. This is usually used to align items to the active camera, for use as billboards or impostors. Since the active camera can change, a reference to it cannot be directly encoded in the scene graph. Instead, it is passed in as an argument to this method.
See the class description and setAlignment
for more
information on how to set up and apply alignments.
reference
- a node to serve as a common alignment reference
for nodes that have no fixed reference in either or both
axes, or null to use this node as the common reference
java.lang.IllegalArgumentException
- if reference
is not in the same scene graph as this node
java.lang.IllegalStateException
- if the zRef
or
yRef
node of any aligned node is not
in the same scene graph as the aligned node
java.lang.IllegalStateException
- if any node is aligned to itself
or its descendant (note: this applies to null alignment
references, as well)
java.lang.ArithmeticException
- if a transformation required in the
alignment computations cannot be computedpublic void setAlignment(Node zRef, int zTarget, Node yRef, int yTarget)
Sets this node to align with the given other node(s), or disables alignment. Alignment can be used, for example, for automatic "look at" behavior for the camera or a spot light, and to create "billboards" that are always facing the active camera directly.
Alignment can be set or disabled for one or both of the Y and Z axes. If it is set for both, the Z alignment is applied first, followed by the Y alignment. The Y alignment is constrained by the Z alignment. If alignment is set for one axis only, it is unconstrained.
Alignment can be disabled for either or both axes by setting
the respective alignment targets to NONE
. If both
alignments are disabled, the orientation is left at its present
state. The original unaligned orientation is not restored.
zRef
- the node to use as reference for aligning the Z axis
of this node, or null to use instead the reference node
passed as an argument to the align
methodzTarget
- the axis of zRef
to align the Z axis
of this node with, or ORIGIN
to have the Z
axis point at the origin of zRef
, or
NONE
to not align the Z axis at allyRef
- the Y axis equivalent of zRef
yTarget
- the Y axis equivalent of zTarget
java.lang.IllegalArgumentException
- if yTarget
or
zTarget
is not one of the symbolic constants
listed above
java.lang.IllegalArgumentException
- if (zRef == yRef) &&
(zTarget == yTarget != NONE)
java.lang.IllegalArgumentException
- if zRef
or
yRef
is this Nodealign
,
getAlignmentTarget
,
getAlignmentReference
setAlignment(null, Node.NONE, null, Node.NONE); // Disabled setAlignment(null, Node.Z_AXIS, null, Node.Y_AXIS); // "Sprite" setAlignment(null, Node.ORIGIN, world, Node.Y_AXIS); // Billboard setAlignment(target, Node.ORIGIN, target, Node.NONE); // Target light setAlignment(target, Node.ORIGIN, world, Node.Y_AXIS); // Target camera // NOTE 1: // The billboard alignment example requires that world space "up" // is Y and billboard space "up" is Z, so that the Z alignment is // constrained by the Y alignment and not vice versa. Otherwise, // the billboard will not stand upright as the camera passes from // above or below; instead, it will lean over and eventually lie // flat on the ground. The M component of the billboard's node // transformation can be used to rotate the billboard into the // right orientation; the R component can not, because it gets // overwritten by the aligned orientation. Another option is to // use an extra Group node. // NOTE 2: // A camera or light is always facing towards its negative Z axis // in its local coordinate system. To make the target camera and // light alignments work as expected, the Z axis must be made to // point in the opposite direction. This can be done by rotating // the node 180 degrees about its local Y axis. This, in turn, // can be done as described in Note 1 (above), or somewhat more // conveniently, using the scale (S) component: camera.scale(-1, 1, -1); // rotate 180 degrees about the Y axis
public int getAlignmentTarget(int axis)
axis
- the node axis to query the target
for; one of Y_AXIS
and Z_AXIS
zTarget
and
yTarget
parameters of setAlignment
java.lang.IllegalArgumentException
- if
axis
is not one of the symbolic constants listed
for axis
abovesetAlignment
,
align
public Node getAlignmentReference(int axis)
Note that alignment reference nodes are
not returned in a call to getReferences
.
axis
- the node axis to query the reference
node for; one of Y_AXIS
and Z_AXIS
java.lang.IllegalArgumentException
- if
axis
is not one of the symbolic constants listed
for axis
abovesetAlignment
,
align
|
M3G 1.1 -- Jun 22, 2005 | |||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |